package org.example.stockdemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.stockdemo.dto.StockGroupItemDTO;
import org.example.stockdemo.entity.StockDetail;
import org.example.stockdemo.entity.StockGroupItem;
import org.example.stockdemo.mapper.StockGroupItemMapper;
import org.example.stockdemo.mapper.StockMapper;
import org.example.stockdemo.service.StockGroupItemService;
import org.example.stockdemo.service.TencentStockService;
import org.example.stockdemo.util.CacheUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class StockGroupItemServiceImpl extends ServiceImpl<StockGroupItemMapper, StockGroupItem> implements StockGroupItemService {

    @Autowired
    private StockGroupItemMapper stockGroupItemMapper;
    @Autowired
    private StockMapper stockMapper;
    @Autowired
    private TencentStockService tencentStockService;

    @Override
    public boolean addStockToGroup(StockGroupItemDTO stockGroupDTO) {

//        查询stockGroupItem 获取排序号最大值
        int sortOrder = getStockMaxSortOrder(stockGroupDTO.getGroupId()) + 1;

        StockGroupItem item = new StockGroupItem();
        item.setStockCode(stockGroupDTO.getStockCode());
        item.setGroupId(stockGroupDTO.getGroupId());
        item.setSortOrder(sortOrder);
        boolean saved = save(item);
        clearStockCache();
        return saved;
    }


    /**
     * 获取stockGroupItem 获取排序号最大值
     *
     * @param groupId
     * @return
     */
    private int getStockMaxSortOrder(Long groupId) {
        LambdaQueryWrapper<StockGroupItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StockGroupItem::getGroupId, groupId)
                .orderByDesc(StockGroupItem::getSortOrder)
                .last("limit 1");
        StockGroupItem stockGroupItem = stockGroupItemMapper.selectOne(queryWrapper);
        return Objects.isNull(stockGroupItem) ? 0 : stockGroupItem.getSortOrder();
    }

    /**
     * 获取stockGroupItem 获取固定序号最大值
     *
     * @param groupId
     * @return
     */
    private int getStockMaxFixedOrder(Long groupId) {
        LambdaQueryWrapper<StockGroupItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StockGroupItem::getGroupId, groupId)
                .orderByDesc(StockGroupItem::getFixedOrder)
                .last("limit 1");
        StockGroupItem stockGroupItem = stockGroupItemMapper.selectOne(queryWrapper);
        return Objects.isNull(stockGroupItem) ? 0 : stockGroupItem.getFixedOrder();
    }


    @Override
    public boolean removeStockFromGroup(String stockCode, Long groupId) {
        LambdaQueryWrapper<StockGroupItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StockGroupItem::getStockCode, stockCode);
        wrapper.eq(StockGroupItem::getGroupId, groupId);
        boolean removed = this.remove(wrapper);
        clearStockCache();
        return removed;
    }


    /**
     * 移动分组
     *
     * @param stockCode
     * @param fromGroupId
     * @param toGroupId
     * @return
     */
    @Override
    public boolean moveStockToGroup(String stockCode, Long fromGroupId, Long toGroupId) {
        boolean updated = lambdaUpdate()
                .eq(StockGroupItem::getStockCode, stockCode)
                .eq(StockGroupItem::getGroupId, fromGroupId)
                .set(StockGroupItem::getGroupId, toGroupId)
                .update();
        clearStockCache();
        return updated;
    }

    @Override
    public List<StockGroupItem> getAllGroup() {
        // 查询所有分组
        LambdaQueryWrapper<StockGroupItem> wrapper = new LambdaQueryWrapper();
        wrapper.select(StockGroupItem::getGroupId)
                .groupBy(StockGroupItem::getGroupId);
        List<StockGroupItem> stockGroupItems = stockGroupItemMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(stockGroupItems)) {
            return Collections.emptyList();
        }
        return stockGroupItems;
    }

    @Override
    public List<StockDetail> getStocksByGroupId(Long groupId) {
        List<StockDetail> stocks = CacheUtil.groupStockCache.get(groupId);
        if (CollectionUtils.isNotEmpty(stocks)) {
            return stocks;
        }
        return getAndCacheStocks(groupId);
    }

    @Override
    public List<StockDetail> getAndCacheStocks(Long groupId) {
        LambdaQueryWrapper<StockGroupItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StockGroupItem::getGroupId, groupId);
        // 根据fixedOrder, sortOrder排序
        queryWrapper.orderByDesc(StockGroupItem::getFixedOrder, StockGroupItem::getSortOrder);

        List<StockGroupItem> stockGroupItems = stockGroupItemMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(stockGroupItems)) {
            return Collections.emptyList();
        }
        List<String> codeList = stockGroupItems.stream().map(StockGroupItem::getStockCode).collect(Collectors.toList());
        List<StockDetail> stockRealtimeQuotes = tencentStockService.getBatchRealtimeQuotes(codeList, true);
        CacheUtil.groupStockCache.put(groupId, stockRealtimeQuotes);
        return stockRealtimeQuotes;
    }

    private void clearStockCache() {
        CacheUtil.groupStockCache.clear();
    }

    /**
     * 置顶股票
     *
     * @param groupId
     * @param stockCode
     */
    @Override
    public boolean pushStockTop(Long groupId, String stockCode) {
        int sortOrder = getStockMaxSortOrder(groupId) + 1;
        if (lambdaUpdate()
                .eq(StockGroupItem::getGroupId, groupId)
                .eq(StockGroupItem::getStockCode, stockCode)
                .set(StockGroupItem::getSortOrder, sortOrder)
                .update()) {
            clearStockCache();
            return true;
        }
        return false;
    }

    /**
     * 固定股票
     *
     * @param groupId
     * @param stockCode
     */
    @Override
    public boolean fixedStockTop(Long groupId, String stockCode) {
        int sortOrder = getStockMaxFixedOrder(groupId) + 1;
        if (lambdaUpdate()
                .eq(StockGroupItem::getGroupId, groupId)
                .eq(StockGroupItem::getStockCode, stockCode)
                .set(StockGroupItem::getFixedOrder, sortOrder)
                .update()) {
            clearStockCache();
            return true;
        }
        return false;
    }

    /**
     * 固定股票
     *
     * @param groupId
     * @param stockCode
     */
    @Override
    public boolean addMonitorFlag(Long groupId, String stockCode) {
        if (lambdaUpdate()
                .eq(StockGroupItem::getGroupId, groupId)
                .eq(StockGroupItem::getStockCode, stockCode)
                .set(StockGroupItem::getMonitorFlag, 1)
                .update()) {
            clearStockCache();
            return true;
        }
        return false;
    }


}